'use client';

import React, { useRef, useEffect, useState } from 'react';
import { init, getInstanceByDom } from 'echarts';
import type { EChartsOption, EChartsType } from 'echarts';

interface EChartBaseProps {
  option: EChartsOption;
  style?: React.CSSProperties;
  className?: string;
  theme?: string;
  loading?: boolean;
  showLoading?: boolean;
  errorMessage?: string;
  fallbackContent?: React.ReactNode;
  emptyDataMessage?: string;
  onEvents?: Record<string, (params: any) => void>;
  shouldRenderChart?: () => boolean;
}

/**
 * 通用ECharts组件
 * 
 * @param option ECharts配置项
 * @param style 样式
 * @param className 类名
 * @param theme 主题
 * @param loading 是否处于加载状态
 * @param showLoading 是否显示加载动画
 * @param errorMessage 错误消息
 * @param fallbackContent 备用内容
 * @param emptyDataMessage 空数据消息
 * @param onEvents 事件处理函数
 * @param shouldRenderChart 是否应该渲染图表的条件函数
 */
const EChartBase: React.FC<EChartBaseProps> = ({
  option,
  style = { height: '400px', width: '100%' },
  className,
  theme,
  loading = false,
  showLoading = true,
  errorMessage,
  fallbackContent,
  emptyDataMessage = '暂无数据',
  onEvents,
  shouldRenderChart = () => true
}) => {
  const chartRef = useRef<HTMLDivElement>(null);
  const chartInstance = useRef<EChartsType | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [isEmpty, setIsEmpty] = useState<boolean>(false);

  // 检查数据是否为空
  const checkIsEmpty = (option: EChartsOption): boolean => {
    if (!option || !option.series) return true;
    
    // 检查series是否为数组且不为空
    if (Array.isArray(option.series)) {
      // 如果series为空数组，则认为是空数据
      if (option.series.length === 0) return true;
      
      // 检查每个系列的数据
      return option.series.every(series => {
        // 对于某些图表类型，data可能不存在或结构不同
        if (!series.data) return true;
        
        // 处理不同类型的数据结构
        if (Array.isArray(series.data)) {
          return series.data.length === 0 || 
                 series.data.every((item: any) => item === null || item === undefined);
        }
        
        // 对于其他情况，检查data是否为空对象
        return Object.keys(series.data as object).length === 0;
      });
    }
    
    // 单一series对象
    if (typeof option.series === 'object') {
      const series = option.series as any;
      if (!series.data) return true;
      
      if (Array.isArray(series.data)) {
        return series.data.length === 0;
      }
      
      return Object.keys(series.data).length === 0;
    }
    
    return true;
  };

  // 初始化图表
  useEffect(() => {
    if (!chartRef.current || !shouldRenderChart()) return;
    
    try {
      const renderedInstance = getInstanceByDom(chartRef.current) || init(chartRef.current, theme);
      
      // 绑定事件
      if (onEvents && renderedInstance) {
        Object.keys(onEvents).forEach(eventName => {
          // 先移除之前的事件
          renderedInstance.off(eventName);
          // 添加新的事件处理函数
          renderedInstance.on(eventName, onEvents[eventName]);
        });
      }
      
      chartInstance.current = renderedInstance;
      setError(null);
    } catch (err) {
      console.error('图表初始化失败:', err);
      setError(err instanceof Error ? err.message : '图表初始化失败');
    }
  }, [theme, shouldRenderChart]);

  // 更新图表配置
  useEffect(() => {
    if (!chartRef.current || !chartInstance.current || error || !shouldRenderChart()) return;
    
    try {
      // 检查数据是否为空
      const dataIsEmpty = checkIsEmpty(option);
      setIsEmpty(dataIsEmpty);
      
      // 如果数据不为空，则设置选项
      if (!dataIsEmpty) {
        chartInstance.current.setOption(option, true);
      }
      
      // 处理加载状态
      if (loading && showLoading) {
        chartInstance.current.showLoading({
          text: '加载中...',
          color: '#4f46e5', // 主色调
          textColor: '#6b7280', // 文字颜色
          maskColor: 'rgba(255, 255, 255, 0.8)', // 遮罩颜色
        });
      } else {
        chartInstance.current.hideLoading();
      }
    } catch (err) {
      console.error('图表更新失败:', err);
      setError(err instanceof Error ? err.message : '图表更新失败');
    }
  }, [option, loading, showLoading, shouldRenderChart]);

  // 处理窗口大小变化
  useEffect(() => {
    const handleResize = () => {
      if (chartInstance.current && !error && shouldRenderChart()) {
        chartInstance.current.resize();
      }
    };

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
      
      // 销毁图表实例
      if (chartInstance.current) {
        chartInstance.current.dispose();
        chartInstance.current = null;
      }
    };
  }, [error, shouldRenderChart]);

  // 渲染错误状态
  if (error || errorMessage) {
    return (
      <div
        style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
        className={`${className || ''} bg-gray-50 dark:bg-gray-800 rounded-md border border-gray-200 dark:border-gray-700`}
      >
        <div className="text-center p-4">
          <svg className="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
          </svg>
          <h3 className="mt-2 text-sm font-medium text-gray-900 dark:text-gray-200">图表加载失败</h3>
          <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{errorMessage || error || '发生错误，无法显示图表'}</p>
          {fallbackContent}
        </div>
      </div>
    );
  }

  // 渲染空数据状态
  if (isEmpty && !loading) {
    return (
      <div
        style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
        className={`${className || ''} bg-gray-50 dark:bg-gray-800 rounded-md border border-gray-200 dark:border-gray-700`}
      >
        <div className="text-center p-4">
          <svg className="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
          </svg>
          <h3 className="mt-2 text-sm font-medium text-gray-900 dark:text-gray-200">{emptyDataMessage}</h3>
          {fallbackContent}
        </div>
      </div>
    );
  }

  // 正常渲染图表
  return <div ref={chartRef} style={style} className={className} />;
};

export default EChartBase; 